package khleuven.mondzorg.domain;

import org.json.JSONException;
import org.json.JSONObject;

public abstract class Entry implements MondAppEntry, Comparable<Entry>{
	
	private final String time_tag;
	private EntryType entrytype;
	private Language language;
	private DestinationGroup destination;
	private Illustrations illustrations;
	
	@Deprecated
	public Entry(EntryType type, Language language, DestinationGroup destination) throws DomainException{
		this.time_tag = "0";
		this.entrytype = type;
		setLanguage(language);
		setDestination(destination);
		setIllustrations(new Illustrations());
	}
	
	public Entry(EntryType type, JSONObject object) throws DomainException{
		this.entrytype = type;
		try {
			this.time_tag = object.getJSONObject(JsonKeysDictionary.JSON_KEY_GS_ENTRY_LAST_MODIFIED_DATE).getString(JsonKeysDictionary.JSON_KEY_ITEM);
		} catch (JSONException e) {
			throw new DomainException(e);
		}
		setLanguage(Language.getFromAbbreviation(JsonKeysDictionary.getStringItem(object, JsonKeysDictionary.JSON_KEY_LANGUAGE)));
		setDestination(DestinationGroup.getFromDbName(JsonKeysDictionary.getStringItem(object, JsonKeysDictionary.JSON_KEY_DESTINATION))); 
		setIllustrations(new Illustrations(JsonKeysDictionary.getStringItem(object, JsonKeysDictionary.JSON_KEY_ILLUSTRATIONS)));
	}
	
	public String getTimeTag(){
		return time_tag;
	}
	
	public EntryType getType() {
		return this.entrytype;
	}
	
	public Language getLanguage() {
		return language;
	}

	private void setLanguage(Language language) {
		this.language = language;
	}

	public DestinationGroup getDestination() {
		return destination;
	}

	private void setDestination(DestinationGroup destination) {
		this.destination = destination;
	}

	protected Illustrations getIllustrations() {
		return illustrations;
	}

	private void setIllustrations(Illustrations illustrations) throws DomainException{
		if(illustrations == null){
			throw new DomainException("use the constructor without illustrations");
		}
		this.illustrations = illustrations;
	}
	
	public void addIllustration(String illustrationid) throws DomainException{
		getIllustrations().add(DentalCareApp.getInstance().getIllustration(illustrationid));		
	}
	
	public abstract String makeStringForList();
	
	@Override
	public String toString(){
		return getType()+": ";
	}
	
	@Override
	public boolean equals(Object o){
		boolean gelijk = false;
		if(o instanceof Entry){
			Entry e = (Entry)(o);
			if(e.getTimeTag().equals(getTimeTag()) &&
					e.getLanguage() == getLanguage() && 
					e.getDestination() == getDestination() && 
					e.getIllustrations().equals(getIllustrations())){
				gelijk = true;
			}
		}
		return gelijk;
	}
	
	public JSONObject toJSon() throws DomainException{
		JSONObject output = new JSONObject();
		JsonKeysDictionary.toStringItem(output, JsonKeysDictionary.JSON_KEY_ENTRY_TYPE, getType().toString());
		JsonKeysDictionary.toStringItem(output, JsonKeysDictionary.JSON_KEY_GS_ENTRY_LAST_MODIFIED_DATE, getTimeTag());
		JsonKeysDictionary.toStringItem(output, JsonKeysDictionary.JSON_KEY_LANGUAGE, getLanguage().getAbbreviation());
		JsonKeysDictionary.toStringItem(output, JsonKeysDictionary.JSON_KEY_DESTINATION, getDestination().getNameInDb());
		JsonKeysDictionary.toStringItem(output, JsonKeysDictionary.JSON_KEY_ILLUSTRATIONS, getIllustrations().toJSonString());
		return output;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((destination == null) ? 0 : destination.hashCode());
		result = prime * result
				+ ((entrytype == null) ? 0 : entrytype.hashCode());
		result = prime * result
				+ ((illustrations == null) ? 0 : illustrations.hashCode());
		result = prime * result
				+ ((language == null) ? 0 : language.hashCode());
		result = prime * result
				+ ((time_tag == null) ? 0 : time_tag.hashCode());
		return result;
	}
	




	public int compareTo(Entry t) {
		if(this.getType().equals(t.getType())) {
			if(this.getDestination().equals(t.getDestination())) {
				if(this.getLanguage().equals(t.getLanguage())) {
					return 0; // responsibility of subclasses to make sure other fields are also incorporated!
				} else {
					return this.getLanguage().compareTo(t.getLanguage());
				}
			} else {
				return this.getDestination().compareTo(t.getDestination());
			}
		} else {
			return this.getType().compareTo(t.getType());
		}
	}
	

}
